import jsPDF from 'jspdf'
import { ExportEngine, ExportType, ExportData, ExportOptions, ExportProgress } from './types'

/**
 * PDF导出引擎
 * 使用jsPDF生成专业格式的分镜脚本PDF
 */
export class PDFExportEngine implements ExportEngine {
  type = ExportType.PDF
  
  /**
   * 生成PDF文件
   */
  async generate(
    data: ExportData, 
    options: ExportOptions,
    onProgress?: (progress: ExportProgress) => void
  ): Promise<Blob> {
    try {
      onProgress?.({
        stage: 'preparing',
        progress: 0,
        message: '准备生成PDF...'
      })
      
      // 创建PDF文档
      const pdf = new jsPDF({
        orientation: options.orientation || 'portrait',
        unit: 'mm',
        format: options.pageSize || 'A4'
      })
      
      onProgress?.({
        stage: 'processing',
        progress: 10,
        message: '添加项目信息...'
      })
      
      // 添加项目信息页
      this.addProjectHeader(pdf, data)
      
      onProgress?.({
        stage: 'processing',
        progress: 20,
        message: '生成场景内容...'
      })
      
      // 添加场景内容
      const scenesToExport = options.includeAll 
        ? data.scenes
        : data.scenes.filter(scene => options.selectedSceneIds?.includes(scene.id))
      
      for (let i = 0; i < scenesToExport.length; i++) {
        const scene = scenesToExport[i]
        const progress = 20 + (i / scenesToExport.length) * 60
        
        onProgress?.({
          stage: 'processing',
          progress,
          message: `处理场景: ${scene.title}`
        })
        
        await this.addScenePage(pdf, scene, options)
        
        // 添加分页（除了最后一个场景）
        if (i < scenesToExport.length - 1) {
          pdf.addPage()
        }
      }
      
      onProgress?.({
        stage: 'processing',
        progress: 85,
        message: '添加统计信息...'
      })
      
      // 添加统计信息页
      if (options.includeStatistics) {
        pdf.addPage()
        this.addStatisticsPage(pdf, data)
      }
      
      onProgress?.({
        stage: 'finalizing',
        progress: 95,
        message: '生成最终文件...'
      })
      
      // 生成Blob
      const pdfBlob = pdf.output('blob')
      
      onProgress?.({
        stage: 'completed',
        progress: 100,
        message: 'PDF生成完成'
      })
      
      return pdfBlob
      
    } catch (error) {
      onProgress?.({
        stage: 'error',
        progress: 0,
        message: '生成PDF时发生错误',
        error: error instanceof Error ? error.message : String(error)
      })
      throw error
    }
  }
  
  /**
   * 添加项目信息头部
   */
  private addProjectHeader(pdf: jsPDF, data: ExportData): void {
    const { projectInfo } = data
    
    // 标题 - 使用ASCII字符以避免字体问题
    pdf.setFontSize(24)
    pdf.text(this.toASCII(projectInfo.title), 20, 30)
    
    // 分割线
    pdf.setLineWidth(0.5)
    pdf.line(20, 35, 190, 35)
    
    // 项目信息
    pdf.setFontSize(12)
    let yPos = 50
    
    if (projectInfo.description) {
      pdf.text(`Project Description: ${this.toASCII(projectInfo.description)}`, 20, yPos)
      yPos += 8
    }
    
    pdf.text(`Created Date: ${projectInfo.createdAt.toLocaleDateString()}`, 20, yPos)
    yPos += 8
    
    pdf.text(`Total Scenes: ${projectInfo.totalScenes}`, 20, yPos)
    yPos += 8
    
    pdf.text(`Total Duration: ${projectInfo.totalDuration.toFixed(1)}s`, 20, yPos)
    yPos += 8
    
    // 目录预留空间
    pdf.setFontSize(14)
    pdf.text('Storyboard Content', 20, yPos + 10)
  }
  
  /**
   * 转换中文为ASCII显示
   */
  private toASCII(text: string): string {
    // 简单的中文字符替换，避免字体问题
    return text
      // 基础词汇
      .replace(/分镜/g, 'Storyboard')
      .replace(/场景/g, 'Scene')
      .replace(/项目/g, 'Project')
      .replace(/演示/g, 'Demo')
      .replace(/脚本/g, 'Script')
      // 场景相关
      .replace(/咖啡厅/g, 'Cafe')
      .replace(/外景/g, 'Exterior')
      .replace(/内景/g, 'Interior')
      .replace(/建立镜头/g, 'Establishing Shot')
      .replace(/门口/g, 'Entrance')
      .replace(/入口/g, 'Entry')
      .replace(/座位/g, 'Seat')
      .replace(/靠窗/g, 'Window-side')
      // 人物动作
      .replace(/主人公/g, 'Protagonist')
      .replace(/入场/g, 'Entry')
      .replace(/思考/g, 'Thinking')
      .replace(/表情/g, 'Expression')
      .replace(/推开/g, 'Push open')
      .replace(/缓步走入/g, 'Walk in slowly')
      .replace(/坐下/g, 'Sit down')
      .replace(/凝视/g, 'Gaze at')
      .replace(/窗外/g, 'Outside window')
      .replace(/若有所思/g, 'Thoughtful')
      // 镜头类型
      .replace(/特写/g, 'Close-up')
      .replace(/近景/g, 'Close shot')
      .replace(/中景/g, 'Medium shot')
      .replace(/全景/g, 'Wide shot')
      .replace(/远景/g, 'Long shot')
      // 拍摄角度
      .replace(/平视/g, 'Eye level')
      .replace(/微仰/g, 'Slightly low')
      .replace(/俯视/g, 'High angle')
      .replace(/仰视/g, 'Low angle')
      // 镜头运动
      .replace(/静止/g, 'Static')
      .replace(/推镜/g, 'Zoom in')
      .replace(/拉镜/g, 'Zoom out')
      .replace(/推轨/g, 'Dolly in')
      .replace(/拉轨/g, 'Dolly out')
      // 光线条件
      .replace(/自然光\(日\)/g, 'Natural daylight')
      .replace(/自然光\(夜\)/g, 'Natural night')
      .replace(/人工光\(亮\)/g, 'Artificial bright')
      .replace(/人工光\(暗\)/g, 'Artificial dim')
      .replace(/混合光/g, 'Mixed lighting')
      // 优先级和复杂度
      .replace(/普通/g, 'Normal')
      .replace(/简单/g, 'Simple')
      .replace(/中等/g, 'Medium')
      .replace(/复杂/g, 'Complex')
      .replace(/高/g, 'High')
      .replace(/低/g, 'Low')
      // 时间和描述
      .replace(/阳光明媚/g, 'Sunny')
      .replace(/早晨/g, 'Morning')
      .replace(/繁忙/g, 'Busy')
      .replace(/氛围/g, 'Atmosphere')
      .replace(/玻璃门/g, 'Glass door')
      || text
  }
  
  /**
   * 添加场景页面
   */
  private async addScenePage(pdf: jsPDF, scene: any, options: ExportOptions): Promise<void> {
    let yPos = 20
    
    // 场景标题
    pdf.setFontSize(16)
    pdf.text(`Scene ${scene.order + 1}: ${this.toASCII(scene.title)}`, 20, yPos)
    yPos += 15
    
    // 分割线
    pdf.setLineWidth(0.3)
    pdf.line(20, yPos, 190, yPos)
    yPos += 10
    
    // 基本信息表格
    pdf.setFontSize(10)
    const leftCol = 20
    const rightCol = 105
    
    // 左列信息
    pdf.text('Shot Info:', leftCol, yPos)
    yPos += 6
    pdf.text(`Shot Type: ${this.toASCII(scene.shotType)}`, leftCol + 5, yPos)
    yPos += 5
    pdf.text(`Camera Angle: ${this.toASCII(scene.cameraAngle)}`, leftCol + 5, yPos)
    yPos += 5
    if (scene.cameraMovement && scene.cameraMovement !== '静止') {
      pdf.text(`Camera Movement: ${this.toASCII(scene.cameraMovement)}`, leftCol + 5, yPos)
      yPos += 5
    }
    
    // 右列信息
    let rightYPos = yPos - 16
    pdf.text('Scene Info:', rightCol, rightYPos)
    rightYPos += 6
    pdf.text(`Location: ${this.toASCII(scene.location)}`, rightCol + 5, rightYPos)
    rightYPos += 5
    pdf.text(`Location Type: ${this.toASCII(scene.locationType)}`, rightCol + 5, rightYPos)
    rightYPos += 5
    pdf.text(`Lighting: ${this.toASCII(scene.lighting)}`, rightCol + 5, rightYPos)
    rightYPos += 5
    
    yPos = Math.max(yPos, rightYPos) + 5
    
    // 时长和制作信息
    pdf.text(`Duration: ${scene.duration}s`, leftCol, yPos)
    pdf.text(`Priority: ${this.toASCII(scene.priority)}`, leftCol + 40, yPos)
    pdf.text(`Complexity: ${this.toASCII(scene.complexity)}`, leftCol + 70, yPos)
    yPos += 10
    
    // 人物和道具
    if (scene.characters.length > 0) {
      pdf.text(`Characters: ${scene.characters.map((c: string) => this.toASCII(c)).join(', ')}`, leftCol, yPos)
      yPos += 6
    }
    
    if (scene.props.length > 0) {
      pdf.text(`Props: ${scene.props.map((p: string) => this.toASCII(p)).join(', ')}`, leftCol, yPos)
      yPos += 6
    }
    
    // 场景描述
    if (scene.description) {
      yPos += 5
      pdf.text('Scene Description:', leftCol, yPos)
      yPos += 6
      
      // 处理长文本换行
      const textLines = pdf.splitTextToSize(this.toASCII(scene.description), 150)
      pdf.text(textLines, leftCol + 5, yPos)
      yPos += textLines.length * 5
    }
    
    // 缩略图占位符（如果启用）
    if (options.includeThumbnails) {
      yPos += 10
      pdf.rect(leftCol, yPos, 60, 45) // 缩略图框
      pdf.setFontSize(8)
      pdf.text('Thumbnail Placeholder', leftCol + 10, yPos + 25)
      yPos += 50
    }
    
    // 备注
    if (scene.notes && scene.notes !== scene.description) {
      yPos += 5
      pdf.text('Production Notes:', leftCol, yPos)
      yPos += 6
      const noteLines = pdf.splitTextToSize(this.toASCII(scene.notes), 150)
      pdf.text(noteLines, leftCol + 5, yPos)
    }
  }
  
  /**
   * 添加统计信息页
   */
  private addStatisticsPage(pdf: jsPDF, data: ExportData): void {
    const { statistics } = data
    let yPos = 30
    
    // 标题
    pdf.setFontSize(18)
    pdf.text('Project Statistics', 20, yPos)
    yPos += 20
    
    // 基础统计
    pdf.setFontSize(12)
    pdf.text('Basic Statistics:', 20, yPos)
    yPos += 10
    
    pdf.setFontSize(10)
    pdf.text(`Total Scenes: ${statistics.totalScenes}`, 25, yPos)
    yPos += 6
    pdf.text(`Total Duration: ${statistics.totalDuration.toFixed(1)}s (${(statistics.totalDuration / 60).toFixed(1)}min)`, 25, yPos)
    yPos += 6
    pdf.text(`Average Duration: ${statistics.averageDuration.toFixed(1)}s`, 25, yPos)
    yPos += 6
    
    if (statistics.longestScene) {
      pdf.text(`Longest Scene: ${this.toASCII(statistics.longestScene.title)} (${statistics.longestScene.duration}s)`, 25, yPos)
      yPos += 6
    }
    
    if (statistics.shortestScene) {
      pdf.text(`Shortest Scene: ${this.toASCII(statistics.shortestScene.title)} (${statistics.shortestScene.duration}s)`, 25, yPos)
      yPos += 6
    }
    
    yPos += 10
    
    // 镜头类型统计
    pdf.setFontSize(12)
    pdf.text('Shot Type Distribution:', 20, yPos)
    yPos += 10
    
    pdf.setFontSize(10)
    Object.entries(statistics.scenesByType).forEach(([type, count]) => {
      pdf.text(`${this.toASCII(type)}: ${count} scenes`, 25, yPos)
      yPos += 6
    })
    
    yPos += 10
    
    // 其他统计
    pdf.setFontSize(12)
    pdf.text('Scene Elements:', 20, yPos)
    yPos += 10
    
    pdf.setFontSize(10)
    pdf.text(`Number of Locations: ${statistics.locationCount}`, 25, yPos)
    yPos += 6
    pdf.text(`Number of Characters: ${statistics.characterCount}`, 25, yPos)
  }
  
  /**
   * 获取支持的导出选项
   */
  getSupportedOptions(): Partial<ExportOptions> {
    return {
      includeThumbnails: true,
      includeTechnicalParams: true,
      includeStatistics: true,
      includeNotes: true,
      pageSize: 'A4',
      orientation: 'portrait',
      quality: 'high'
    }
  }
}